#include <iostream>

using namespace std;


class Animal{
private:
	char *name;
	int age;

public:
	Animal(char *name, int age)
	{
		this->name = name;
		this->age = age;
	}
	char * getName()
	{
		return this->name;
	}
	int getAge()
	{
		return this->age;
	}
	void printText()
	{
		cout << this->name << ", " << this->age << endl;
	}
};

// C++中的继承方式是子类名称后添加冒号":"，然后跟上需要集成的父类
// 如果需要访问父类的函数，需要在继承的位置添加继承修饰符 public private protected
class Cat : public Animal{

public:
	// 默认会调用父类的无参构造，但是父类只有有参构造，所以需要显示调用父类的有参构造
	Cat(char *name, int age) : Animal(name,age)
	{
	
	}

};

class Food{
private:
	string foodName;
public:
	Food(string name)
	{
		this->foodName = name;
	}

	string getFoodName()
	{
		return this->foodName;
	}
};

// 构造函数中初始化属性
class Dog : public Animal{

public:
	char *course;
	Food food;
public:
	// 构造函数中对父类中的属性进行赋值或者对本类中的户型进行赋值
	Dog(char *name, int age, char *course, string foodName):Animal(name,age),course(course),food(foodName)
	{
		// 获取在这个位置进行初始化也是可以的
		course = (char *)"KKK";
	}
	void printText()
	{
		cout << "course: " << course << ", food: " << food.getFoodName().c_str() << endl;
	}
};

/*
 * C++ 中允许多继承，但是不允许有二义性，Java中不允许多继承。
 * */
// 羊
class Sheep{
private:
	int color;
public:
	Sheep(int color)
	{
		this->color = color;
	}
	
	int getColor()
	{
		return this->color;
	}
};
// 山羊
class Goat: public Animal, public Sheep{
private:
	int weight;
public:
	Goat(char *name, int age, int color, int weight):Animal(name,age), Sheep(color), weight(weight)
	{
	}

	int getWeight()
	{
		return this->weight;
	}
	void printInfo()
	{
		cout << "---------------------------" << endl;
		cout << "name: " << this->getName() << endl;
		cout << "age: " << this->getAge() << endl;
		cout << "color: " << this->getColor() << endl;
		cout << "weight: " << this->getWeight() << endl;
		cout << "---------------------------" << endl;
	}
};

// 虚继承（解决二义性）
class A{
public:
	char *name;
public:
	virtual void eat()
	{
		cout << "A.eat()" << endl;
	}
};
// virtual关键字确保相同属性或者函数，只有支付拷贝
class B: virtual public A{

	virtual void eat()
	{
		cout << "B.eat()" << endl;
	}

};

class C: virtual public A{

	virtual void eat()
	{
		cout << "C.eat()" << endl;
	}

};

class D: public B, public C{

	virtual void eat()
	{
		cout << "D.eat()" << endl;
	}

};

void printA(A *a){

	a->eat();
	
}

int main()
{

	Cat *cat = new Cat((char *)"Tom",12);
	Dog *dog = new Dog((char *)"Aiim",123,(char *)"数学","狗粮");
	Goat *goat = new Goat((char *)"山羊",32,1,100);

	cat->printText();
	dog->printText();
	goat->printInfo();

	delete(dog);
	delete(cat);
	delete(goat);

	// 虚继承
	D *d = new D();
	// 因为D同时继承了B和C，B和C又同时继承了A，所以需要使用虚继承解决D类中到底使用B还是C中name属性
	d->name = (char *)"GGG";
	cout << "D.name: " << d->name << endl;

	// 多态，子类通过virtual关键字重写父类的函数
	// 多态是在继承的基础上，相同函数名称，在不同子类中的实现
	// C++中的多态分为：动态多态（父子类函数的重写），静态多态（函数的重载）
	A *b = new B();
	A *c = new C();
	
	printA(b);
	printA(c);

	return 0;
}


